package com.cocolover2.andbase.widget.refresh.header;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import com.cocolover2.andbase.R;


public class RefreshCircleView extends View {

    private static final float INER_RADIUS = 10;
    private static final float CIRCLE_SPEC_SIZE = 5;
    private static final float BALL_RADIUS = 2;
    private static final float LINE_WIDTH = 1;

    //内圆的半径
    private float mInerRadius;
    //内圆到外圆的间距
    private float mCircleSpecSize;
    //外圆的线的宽度
    private float mLineWidth;
    //圆球的半径
    private float mBallRadius;

    private int mInerCircleColor = Color.GRAY;
    private int mLineColor = Color.GRAY;
    private int mBallColor = Color.GRAY;


    //圆球的中心的x坐标
    private float mBallCenterX;
    //圆球的中心的y坐标
    private float mBallCenterY;

    private boolean isMoveBall;

    private boolean isRunning;
    private float mSpeed;
    private float mDegree = 0;
    private Paint mPaint;


    public RefreshCircleView(Context context) {
        this(context, null);
    }

    public RefreshCircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RefreshCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RefreshCircleView);

        try {
            mInerRadius = array.getDimension(R.styleable.RefreshCircleView_inerRadius, dp2Px(INER_RADIUS));
            mCircleSpecSize = array.getDimension(R.styleable.RefreshCircleView_circleSpacSize, dp2Px(CIRCLE_SPEC_SIZE));
            mBallRadius = array.getDimension(R.styleable.RefreshCircleView_ballRadius, dp2Px(BALL_RADIUS));
            mLineWidth = array.getDimension(R.styleable.RefreshCircleView_lineWidth, dp2Px(LINE_WIDTH));

            setSpeed(array.getFloat(R.styleable.RefreshCircleView_speed, 0.4f));

            mBallColor = array.getColor(R.styleable.RefreshCircleView_ballColor, Color.GRAY);
            mInerCircleColor = array.getColor(R.styleable.RefreshCircleView_inerCircleColor, Color.GRAY);
            mLineColor = array.getColor(R.styleable.RefreshCircleView_lineColor, Color.GRAY);
        } finally {
            array.recycle();
        }

        mPaint = new Paint();
        mPaint.setColor(mInerCircleColor);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL);


    }

    public void setCircleSpecSize(float circleSpecSize) {
        mCircleSpecSize = dp2Px(circleSpecSize);
    }

    public void setInerRadius(float inerRadius) {
        mInerRadius = dp2Px(inerRadius);
    }

    public void setLineWidth(float lineWidth) {
        mLineWidth = lineWidth;
    }

    public void setBallRadius(float ballRadius) {
        mBallRadius = dp2Px(ballRadius);
    }

    public void setInerCircleColor(int inerCircleColor) {
        mInerCircleColor = inerCircleColor;
    }

    public void setLineColor(int lineColor) {
        mLineColor = lineColor;
    }

    public void setBallColor(int ballColor) {
        mBallColor = ballColor;
    }


    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        stopAnimation();
        clearFocus();
        clearAnimation();
        mPaint = null;


    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        final int width = (int) ((mInerRadius + mCircleSpecSize + mLineWidth + 0.5f) * 2 + mBallRadius) + getPaddingRight() + getPaddingLeft();
        final int height = (int) ((mInerRadius + mCircleSpecSize + mLineWidth + 0.5f) * 2 + mBallRadius) + getPaddingBottom() + getPaddingTop();

        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(width, height);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(width, heightSize);
        } else if (heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSize, height);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        final int xCenter = getMeasuredWidth() / 2;
        final int yCenter = getMeasuredHeight() / 2;
        //绘制内圆
        canvas.drawCircle(xCenter, yCenter, mInerRadius, mPaint);
        //绘制圆环
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mLineWidth);
        mPaint.setColor(mLineColor);
        canvas.drawCircle(xCenter, yCenter, mInerRadius + mCircleSpecSize, mPaint);
//绘制小球
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(mBallColor);
        if (!isMoveBall) {
            mBallCenterX = xCenter + mInerRadius + mCircleSpecSize;
            mBallCenterY = yCenter;
        }
        canvas.drawCircle(mBallCenterX, mBallCenterY, mBallRadius, mPaint);
    }

    public void moveBall(float degree) {
        isMoveBall = true;
        final float baseRadius = mInerRadius + mCircleSpecSize;
        mBallCenterX = getMeasuredWidth() / 2.0f + (float) (baseRadius * Math.cos(Math.toRadians(degree)));
        mBallCenterY = getMeasuredHeight() / 2.0f + (float) (baseRadius * Math.sin(Math.toRadians(degree)));
        mDegree = degree;
        invalidate();
    }

    public void setSpeed(float speed) {
        if (speed <= 0 || speed > 1)
            throw new IllegalArgumentException("speed should be in (0.0,1.0]");
        mSpeed = speed * 10;
    }

    public void startAnimtion() {
        if (!isRunning) {
            post(mRunnable);
            isRunning = true;
        }
    }


    private Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            mDegree -= mSpeed;
            if (Math.abs(mDegree) >= 360)
                mDegree = 0;
            moveBall(mDegree);
            postDelayed(mRunnable, 5);
        }
    };

    public void stopAnimation() {
        removeCallbacks(mRunnable);
        isRunning = false;
    }

    public boolean isRunning() {
        return isRunning;
    }

    public float dp2Px(float value) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, getResources().getDisplayMetrics());
    }
}
